﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Algobox.JuicyLib.Apps.Stoxx.Structure;

namespace Algobox.JuicyLib.Apps.Stoxx.Files
{
    public static class OpeningTMIComponents
    {
        public static Uri URL { get { return new Uri("http://www.stoxx.com/download/data/change_files/opening_tmi_components.txt"); } }

        const int HEADER_DATE_LINE = 0;
        const int HEADER_DATE_LOC = 2;

        const int DATA_START_LINE = 2;
        const int DATA_MINIMUM_LENGTH = 23;

        const int DATA_Country = 0;
        const int DATA_Exchange = 1;
        const int DATA_Name = 2;
        const int DATA_Forex = 3;
        const int DATA_RIC = 4;
        const int DATA_ISIN = 5;
        //const int DATA_CUSIP = 6;
        const int DATA_Sedol = 7;
        const int DATA_InternalNo = 8;
        const int DATA_Shares = 9;
        const int DATA_Float = 10;
        const int DATA_Close = 11;
        const int DATA_MCapLocal = 12;
        const int DATA_MCapEUR = 13;
        const int DATA_MCapUSD = 14;
        //const int DATA_Industry = 15;
        //const int DATA_Supersector = 16;
        //const int DATA_Sector = 17;
        const int DATA_Subsector = 18;
        //const int DATA_Style = 19;
        //const int DATA_Sustainability = 20;
        //const int DATA_SustainabilityEx = 21;
        const int DATA_Size = 22;


        /// <summary>
        /// Updates a listing dictionary with the compostion data from a specified file
        /// </summary>
        /// <param name="file">The opening TMI composition file</param>
        /// <param name="data">Dictionary of listing data to be updated</param>
        /// <param name="dataDate">date of the file being parsed</param>
        /// <returns></returns>
        static public bool TryParseFile(ref string file, Dictionary<string, StoxxListing> data, out DateTime dataDate)
        {
            dataDate = DateTime.Today;

            if(data == null)
                data = new Dictionary<string, StoxxListing>();

            // uses more memory... but easier to code!
            string[] lines = file.Split('\n');

            // get first line
            string[] line = lines[HEADER_DATE_LINE].Split(';');

            // check header length
            if (line.Length <= HEADER_DATE_LOC)
                return false;

            // parse date string from header
            if (!DateTime.TryParse(line[HEADER_DATE_LOC], out dataDate))
                return false;


            StoxxListing listing;
            string ric;
            Algobox.JuicyLib.MarketData.MarketDataConstants.MarketMICS market;
            Algobox.JuicyLib.MarketData.MarketDataConstants.Currencies currency;

            // skip header lines and start extracting data from 3rd line (index 2)
            for (int i = DATA_START_LINE; i < lines.Length; ++i)
            {
                // get teh line elements
                line = lines[i].Split(';');

                if (line.Length < DATA_MINIMUM_LENGTH)
                    continue;

                // use RIC as the key
                ric = line[DATA_RIC].Trim();

                // listing exists?
                if (!data.TryGetValue(ric, out listing))
                {
                    // check line length
                    if (line.Length < DATA_MINIMUM_LENGTH)
                        return false;

                    // parse MarketMIC
                    if (!StoxxAdaptor.TryGetMarketMIC(line[DATA_Exchange].Trim(), out market))
                        return false;

                    // parse Currency
                    if (!JuicyLib.MarketData.MarketDataConstants.TryParseCurrency(line[DATA_Forex].Trim(), out currency))
                        return false;

                    // create the listing
                    listing = new StoxxListing(market, currency, ric, line[DATA_ISIN].Trim());

                    // store new listing
                    data.Add(listing.RIC, listing);
                }

                // now assign the stuff from this file

                decimal dec;                
                int integer;
                long longInt;

                if (!Decimal.TryParse(line[DATA_Close], out dec))
                    return false;
                listing.Close = dec;

                if (!Decimal.TryParse(line[DATA_Float], out dec))
                    return false;
                listing.Float = dec;

                if (!Int32.TryParse(line[DATA_Subsector], out integer))
                    return false;
                listing.IndustryCode = integer;
                                
                listing.InternalNumber = line[DATA_InternalNo].Trim();

                if (!Decimal.TryParse(line[DATA_MCapEUR], out dec))
                    return false;
                listing.MCapEUR = integer;

                if (!Decimal.TryParse(line[DATA_MCapLocal], out dec))
                    return false;
                listing.MCapLocal = integer;

                if (!Decimal.TryParse(line[DATA_MCapUSD], out dec))
                    return false;
                listing.MCapUSD = integer;
                
                listing.Name = line[DATA_Name].Trim();

                listing.SEDOL = line[DATA_Sedol].Trim();

                if (!Int64.TryParse(line[DATA_Shares], out longInt))
                    return false;
                listing.Shares = longInt;

                // market cap ranking
                listing.Size = 
                    line[DATA_Size].Trim() == "L" ? 
                        Algobox.JuicyLib.MarketData.MarketDataConstants.MarketCapSizes.Large 
                        : line[DATA_Size].Trim() == "M" 
                            ? Algobox.JuicyLib.MarketData.MarketDataConstants.MarketCapSizes.Medium 
                            : Algobox.JuicyLib.MarketData.MarketDataConstants.MarketCapSizes.Small;
                
                
            }


            return true;
        }


    }
}
